using CollabApp.Domain.Entities.Game;

namespace CollabApp.Domain.Services.Game;

/// <summary>
/// 画线圈地游戏 - 玩家状态管理服务接口
/// 
/// 职责说明：
/// 1. 管理游戏中玩家的完整状态（位置、画线、领地、道具）
/// 2. 处理玩家移动和画线轨迹的实时更新
/// 3. 执行碰撞检测和死亡/复活机制
/// 4. 计算和维护玩家领地面积和排名
/// 5. 管理道具拾取、使用和效果系统
/// 
/// 业务规则遵循：
/// - 严格按照画线圈地游戏规则执行碰撞检测
/// - 玩家死亡后5秒复活，带有无敌时间
/// - 实时计算领地面积并更新排名
/// - 道具效果时长和作用严格按照游戏设定
/// - 确保游戏公平性和一致性
/// 
/// 设计原则：
/// - 所有操作异步执行，支持高并发
/// - 使用事件驱动模式通知状态变更
/// - 实现完整的错误处理和业务验证
/// - 支持实时状态查询和历史追踪
/// </summary>
public interface IPlayerStateService
{
    #region 玩家基础状态管理
    
    /// <summary>
    /// 获取玩家完整游戏状态
    /// 
    /// 返回信息包括：
    /// 1. 基础信息：ID、姓名、颜色、位置
    /// 2. 游戏状态：画线状态、生存状态、无敌状态
    /// 3. 领地信息：拥有的所有领地、总面积、排名
    /// 4. 道具信息：背包道具、活跃效果、剩余时长
    /// 5. 统计信息：移动距离、死亡次数、击杀次数
    /// 
    /// 性能优化：
    /// - 支持缓存机制，减少数据库查询
    /// - 增量更新，只返回变化的部分
    /// - 批量查询，支持同时获取多个玩家状态
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <returns>玩家完整状态信息</returns>
    Task<PlayerGameState?> GetPlayerStateAsync(Guid gameId, Guid playerId);
    
    /// <summary>
    /// 获取游戏中所有玩家状态
    /// 
    /// 用途：
    /// 1. 游戏界面显示所有玩家信息
    /// 2. 排行榜计算和显示
    /// 3. 游戏结束时的最终统计
    /// 4. 管理员监控和调试
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <returns>所有玩家状态列表</returns>
    Task<List<PlayerGameState>> GetAllPlayerStatesAsync(Guid gameId);
    
    /// <summary>
    /// 初始化玩家游戏状态
    /// 
    /// 初始化内容：
    /// 1. 分配玩家专属颜色（红、蓝、绿、黄、紫、橙、粉、青）
    /// 2. 设置出生点位置（地图边缘均匀分布）
    /// 3. 创建初始安全区域（出生点周围小片领地）
    /// 4. 初始化统计数据和背包
    /// 5. 设置玩家状态为Idle
    /// 
    /// 分配规则：
    /// - 颜色按加入顺序分配，避免重复
    /// - 出生点距离其他玩家尽可能远
    /// - 初始安全区域大小固定（50x50像素）
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="playerName">玩家昵称</param>
    /// <returns>初始化结果，包含分配的颜色和出生点</returns>
    Task<PlayerInitResult> InitializePlayerStateAsync(Guid gameId, Guid playerId, string playerName);
    
    #endregion
    
    #region 移动和画线系统
    
    /// <summary>
    /// 更新玩家位置并处理移动逻辑
    /// 
    /// 移动处理流程：
    /// 1. 验证移动的合法性（速度限制、边界检查）
    /// 2. 计算实际移动距离和方向
    /// 3. 检测移动路径上的碰撞（边界、障碍物、其他玩家轨迹）
    /// 4. 如果正在画线，添加轨迹点
    /// 5. 更新玩家统计数据（移动距离）
    /// 6. 触发相关游戏事件
    /// 
    /// 碰撞处理：
    /// - 边界碰撞：阻止移动，保持原位置
    /// - 障碍物碰撞：阻止移动，保持原位置
    /// - 轨迹碰撞：如果正在画线，触发死亡；否则正常穿过
    /// - 领地穿越：允许穿越，但不能在其他玩家领地内开始画线
    /// 
    /// 速度加成：
    /// - 基础速度：每秒100像素
    /// - 闪电道具：速度提升50%，每秒150像素
    /// - 速度限制：防止作弊，最大不超过200像素/秒
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="newPosition">目标位置</param>
    /// <param name="timestamp">移动时间戳</param>
    /// <param name="isDrawing">是否正在画线</param>
    /// <returns>位置更新结果，包含实际位置和碰撞信息</returns>
    Task<PositionUpdateResult> UpdatePlayerPositionAsync(
        Guid gameId, 
        Guid playerId, 
        Position newPosition, 
        DateTime timestamp, 
        bool isDrawing = false);
    
    /// <summary>
    /// 玩家开始画线
    /// 
    /// 开始条件检查：
    /// 1. 玩家必须处于Idle状态（非死亡、非画线中）
    /// 2. 开始位置必须在玩家的领地内或出生点
    /// 3. 玩家不能处于其他玩家的领地内
    /// 4. 玩家不能处于无敌状态结束前
    /// 
    /// 开始画线处理：
    /// 1. 验证开始位置的合法性
    /// 2. 清空之前的轨迹（如果有）
    /// 3. 设置玩家状态为Drawing
    /// 4. 记录画线开始时间和位置
    /// 5. 初始化轨迹点列表
    /// 6. 广播画线开始事件
    /// 
    /// 错误情况：
    /// - 不在自己领地内开始：返回错误
    /// - 已经在画线中：返回错误
    /// - 玩家已死亡：返回错误
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="startPosition">开始画线的位置</param>
    /// <returns>画线开始结果</returns>
    Task<DrawingStartResult> StartDrawingAsync(Guid gameId, Guid playerId, Position startPosition);
    
    /// <summary>
    /// 玩家停止画线并尝试圈地
    /// 
    /// 停止画线处理：
    /// 1. 验证玩家确实在画线状态
    /// 2. 检查画线轨迹是否形成闭合回路
    /// 3. 如果闭合，计算新领地面积
    /// 4. 验证新领地的合法性（不与现有领地冲突）
    /// 5. 更新玩家领地和面积统计
    /// 6. 设置玩家状态回到Idle
    /// 7. 广播圈地成功/失败事件
    /// 
    /// 闭合回路判定：
    /// 1. 轨迹终点必须回到玩家的现有领地
    /// 2. 轨迹不能自相交（除了起点和终点）
    /// 3. 形成的区域必须有有效面积（>100像素²）
    /// 
    /// 面积计算：
    /// - 使用多边形面积计算算法（Shoelace公式）
    /// - 排除已属于其他玩家的区域
    /// - 包含区域内的道具和中立区域
    /// 
    /// 特殊情况：
    /// - 未形成闭合：清除轨迹，回到Idle状态
    /// - 包含其他玩家：只获得未被占领的部分
    /// - 面积过小：不获得领地，清除轨迹
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="endPosition">结束画线的位置</param>
    /// <returns>画线结束结果，包含新获得的领地信息</returns>
    Task<DrawingEndResult> StopDrawingAsync(Guid gameId, Guid playerId, Position endPosition);
    
    #endregion
    
    #region 碰撞和战斗系统
    
    /// <summary>
    /// 处理玩家轨迹被其他玩家碰撞（截断死亡）
    /// 
    /// 碰撞检测逻辑：
    /// 1. 检测碰撞发生的精确位置和时间
    /// 2. 验证碰撞的合法性（攻击者不能是自己）
    /// 3. 确认被攻击者正在画线状态
    /// 4. 计算碰撞的影响范围
    /// 
    /// 死亡处理：
    /// 1. 立即清除被攻击者的所有轨迹
    /// 2. 设置被攻击者状态为Dead
    /// 3. 记录死亡原因和攻击者信息
    /// 4. 更新攻击者击杀统计
    /// 5. 启动5秒复活倒计时
    /// 6. 广播玩家死亡事件
    /// 
    /// 护盾道具效果：
    /// - 如果被攻击者有活跃的护盾：免疫此次攻击
    /// - 消耗护盾效果，继续游戏
    /// - 显示护盾抵挡特效
    /// 
    /// 统计更新：
    /// - 被攻击者：死亡次数+1
    /// - 攻击者：击杀次数+1
    /// - 游戏总体：总死亡数+1
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="victimPlayerId">被攻击的玩家标识</param>
    /// <param name="collisionPosition">碰撞发生位置</param>
    /// <param name="attackerPlayerId">攻击者玩家标识（可选，可能是自己撞到自己）</param>
    /// <returns>碰撞处理结果</returns>
    Task<PlayerCollisionHandleResult> HandleTrailCollisionAsync(
        Guid gameId, 
        Guid victimPlayerId, 
        Position collisionPosition, 
        Guid? attackerPlayerId = null);
    
    /// <summary>
    /// 处理玩家死亡的完整流程
    /// 
    /// 死亡类型：
    /// 1. 轨迹被其他玩家碰撞（最常见）
    /// 2. 撞到自己的轨迹（自杀）
    /// 3. 撞到地图边界（边界死亡）
    /// 4. 撞到障碍物（障碍死亡）
    /// 5. 其他特殊情况（如炸弹攻击）
    /// 
    /// 死亡处理步骤：
    /// 1. 记录死亡时间、位置和原因
    /// 2. 清除玩家当前所有轨迹
    /// 3. 保留玩家已占领的领地
    /// 4. 更新玩家状态为Dead
    /// 5. 计算复活倒计时（5秒）
    /// 6. 清除玩家身上的临时道具效果
    /// 7. 更新死亡统计数据
    /// 8. 广播死亡事件给所有玩家
    /// 
    /// 复活准备：
    /// - 设置复活位置为出生点
    /// - 预计算复活后的无敌时间（5秒）
    /// - 清理死亡位置周围的干扰因素
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">死亡的玩家标识</param>
    /// <param name="deathReason">死亡原因描述</param>
    /// <param name="killerId">击杀者标识（如果有）</param>
    /// <param name="deathPosition">死亡位置</param>
    /// <returns>死亡处理结果</returns>
    Task<DeathResult> HandlePlayerDeathAsync(
        Guid gameId, 
        Guid playerId, 
        string deathReason, 
        Guid? killerId = null, 
        Position? deathPosition = null);
    
    /// <summary>
    /// 复活已死亡的玩家
    /// 
    /// 复活条件检查：
    /// 1. 玩家必须处于Dead状态
    /// 2. 复活倒计时必须已结束
    /// 3. 游戏必须仍在进行中
    /// 4. 出生点位置必须安全（无其他玩家占据）
    /// 
    /// 复活处理：
    /// 1. 将玩家传送到出生点位置
    /// 2. 设置玩家状态为Invulnerable（无敌）
    /// 3. 启动5秒无敌时间倒计时
    /// 4. 重置玩家速度和临时效果
    /// 5. 清空画线轨迹缓存
    /// 6. 广播玩家复活事件
    /// 
    /// 无敌机制：
    /// - 无敌期间不会因碰撞死亡
    /// - 无敌期间不能画线
    /// - 无敌期间可以正常移动
    /// - 视觉效果：玩家闪烁显示
    /// - 5秒后自动结束无敌状态
    /// 
    /// 异常处理：
    /// - 出生点被占据：延迟复活，等待位置清空
    /// - 复活过程中断：重新开始复活流程
    /// - 游戏已结束：取消复活操作
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">要复活的玩家标识</param>
    /// <returns>复活操作结果</returns>
    Task<RespawnResult> RespawnPlayerAsync(Guid gameId, Guid playerId);
    
    #endregion
    
    #region 领地和排名系统
    
    /// <summary>
    /// 计算玩家当前总领地面积
    /// 
    /// 计算方法：
    /// 1. 遍历玩家拥有的所有领地区域
    /// 2. 使用几何算法计算每块领地的精确面积
    /// 3. 处理领地重叠部分（去重计算）
    /// 4. 排除被其他玩家侵占的部分
    /// 5. 累加得出总面积
    /// 
    /// 面积单位：
    /// - 使用像素平方（px²）作为基础单位
    /// - 支持转换为百分比（相对于地图总面积）
    /// - 支持转换为游戏内积分
    /// 
    /// 优化策略：
    /// - 使用空间索引加速面积计算
    /// - 缓存计算结果，避免重复计算
    /// - 增量更新，只重新计算变化的部分
    /// 
    /// 精度保证：
    /// - 使用高精度浮点数计算
    /// - 考虑像素边界的影响
    /// - 处理边缘情况和数值误差
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <returns>领地计算结果</returns>
    Task<TerritoryResult> CalculatePlayerTerritoryAsync(Guid gameId, Guid playerId);
    
    /// <summary>
    /// 获取游戏实时排名
    /// 
    /// 排名规则：
    /// 1. 主要依据：当前领地总面积（降序）
    /// 2. 面积相同时：先达到该面积的玩家排名靠前
    /// 3. 同时达到：按玩家加入游戏的顺序
    /// 4. 死亡玩家：保持死亡前的排名
    /// 5. 离线玩家：保持离线前的排名
    /// 
    /// 排名计算：
    /// - 实时计算，每次移动/圈地后更新
    /// - 支持缓存机制，减少计算开销
    /// - 提供排名变化历史记录
    /// - 支持并发访问和更新
    /// 
    /// 显示信息：
    /// - 排名位置（1-8名）
    /// - 玩家基本信息（昵称、颜色）
    /// - 当前领地面积和百分比
    /// - 领地数量统计
    /// - 当前状态（存活/死亡/离线）
    /// 
    /// 性能优化：
    /// - 批量计算所有玩家面积
    /// - 使用内存排序而非数据库排序
    /// - 支持分页查询大量玩家
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <returns>实时排名列表</returns>
    Task<List<PlayerGameRanking>> GetGameRankingAsync(Guid gameId);
    
    #endregion
    
    #region 道具系统
    
    /// <summary>
    /// 玩家拾取地图上的道具
    /// 
    /// 拾取条件检查：
    /// 1. 玩家必须存活（非死亡状态）
    /// 2. 玩家位置与道具位置足够接近（<20像素）
    /// 3. 道具必须仍然存在且未过期
    /// 4. 玩家背包未满（最多持有3个道具）
    /// 5. 玩家不处于无敌状态
    /// 
    /// 拾取处理：
    /// 1. 验证拾取条件的合法性
    /// 2. 从地图上移除该道具
    /// 3. 将道具添加到玩家背包
    /// 4. 更新道具拾取统计
    /// 5. 广播道具被拾取事件
    /// 6. 触发道具拾取音效和特效
    /// 
    /// 道具类型识别：
    /// - 闪电道具：金黄色闪电图标
    /// - 护盾道具：蓝色盾牌图标
    /// - 炸弹道具：红色炸弹图标
    /// 
    /// 背包管理：
    /// - 同类道具可叠加
    /// - 不同道具分别计数
    /// - 背包满时阻止拾取
    /// - 支持道具丢弃功能
    /// 
    /// 异常处理：
    /// - 道具已被其他玩家拾取：返回失败
    /// - 网络延迟导致的重复拾取：去重处理
    /// - 背包状态不一致：重新同步
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="itemId">道具标识</param>
    /// <param name="pickupPosition">拾取位置</param>
    /// <returns>道具拾取结果</returns>
    Task<ItemPickupResult> PickupItemAsync(
        Guid gameId, 
        Guid playerId, 
        Guid itemId, 
        Position pickupPosition);
    
    /// <summary>
    /// 玩家使用背包中的道具
    /// 
    /// 道具效果详解：
    /// 
    /// 1. 闪电道具 (Lightning)：
    ///    - 效果：移动速度提升50%
    ///    - 持续时间：10秒
    ///    - 视觉效果：玩家周围闪电特效
    ///    - 叠加规则：不可叠加，重复使用刷新时间
    ///    - 使用限制：任何状态下都可使用
    /// 
    /// 2. 护盾道具 (Shield)：
    ///    - 效果：免疫下一次轨迹碰撞攻击
    ///    - 持续时间：15秒或被攻击一次
    ///    - 视觉效果：玩家周围蓝色护盾光环
    ///    - 叠加规则：不可叠加，重复使用刷新时间
    ///    - 使用限制：死亡状态下不可使用
    /// 
    /// 3. 炸弹道具 (Bomb)：
    ///    - 效果：清除指定位置周围轨迹（半径100像素）
    ///    - 持续时间：瞬间效果
    ///    - 视觉效果：爆炸动画和声效
    ///    - 目标选择：需要指定目标位置
    ///    - 使用限制：不能在自己领地内使用
    /// 
    /// 使用处理流程：
    /// 1. 验证玩家背包中是否有该道具
    /// 2. 检查道具使用条件和限制
    /// 3. 消耗背包中的道具数量
    /// 4. 应用道具效果到玩家状态
    /// 5. 设置效果持续时间和属性
    /// 6. 广播道具使用事件
    /// 7. 更新道具使用统计
    /// 
    /// 特殊情况处理：
    /// - 炸弹道具：需要验证目标位置合法性
    /// - 效果冲突：新效果覆盖旧效果
    /// - 使用失败：返还道具到背包
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="itemType">要使用的道具类型</param>
    /// <param name="targetPosition">目标位置（炸弹道具需要）</param>
    /// <returns>道具使用结果</returns>
    Task<ItemUseResult> UseItemAsync(
        Guid gameId, 
        Guid playerId, 
        DrawingGameItemType itemType, 
        Position? targetPosition = null);
    
    #endregion
}

#region 数据传输对象和枚举

/// <summary>
/// 玩家画线状态枚举
/// </summary>
public enum PlayerDrawingState
{
    Idle,           // 空闲状态 - 玩家可以开始画线
    Drawing,        // 正在画线 - 玩家正在移动并留下轨迹
    Dead,           // 死亡状态 - 玩家已死亡，无法移动
    Respawning,     // 重生中 - 死亡后等待复活
    Invulnerable    // 无敌状态 - 复活后5秒内免疫攻击
}

/// <summary>
/// 画线圈地游戏道具类型枚举
/// </summary>
public enum DrawingGameItemType
{
    Lightning,      // 闪电道具 - 移动速度提升50%，持续10秒
    Shield,         // 护盾道具 - 免疫一次截断攻击，持续15秒
    Bomb,           // 炸弹道具 - 清除周围小范围内所有玩家轨迹
    SpeedBoost,     // 加速道具 - 移动速度提升（与闪电类似）
    SlowTrap,       // 减速陷阱 - 放置陷阱减缓其他玩家
    Teleport        // 传送道具 - 瞬移到指定位置
}

/// <summary>
/// 画线圈地游戏碰撞类型枚举
/// </summary>
public enum DrawingGameCollisionType
{
    TrailCollision,     // 轨迹碰撞（截断）- 最常见的死亡原因
    TerritoryEntry,     // 进入其他玩家领地 - 可以穿越但不能画线
    BoundaryHit,        // 撞到地图边界 - 阻止移动
    ObstacleHit         // 撞到障碍物 - 阻止移动
}

/// <summary>
/// 玩家游戏状态 - 完整的玩家信息
/// </summary>
public class PlayerGameState
{
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public string PlayerColor { get; set; } = string.Empty;
    public Position CurrentPosition { get; set; } = new();
    public Position SpawnPoint { get; set; } = new();
    public PlayerDrawingState State { get; set; } = PlayerDrawingState.Idle;
    public List<Position> CurrentTrail { get; set; } = new();
    public List<Territory> OwnedTerritories { get; set; } = new();
    public float TotalTerritoryArea { get; set; }
    public int CurrentRank { get; set; }
    public List<DrawingGameItemType> Inventory { get; set; } = new();
    public List<ActiveEffect> ActiveEffects { get; set; } = new();
    public bool IsInvulnerable { get; set; }
    public DateTime? InvulnerabilityEndTime { get; set; }
    public DateTime LastActivity { get; set; }
    public PlayerGameStatistics Statistics { get; set; } = new();
}

/// <summary>
/// 玩家初始化结果
/// </summary>
public class PlayerInitResult
{
    public bool Success { get; set; }
    public string AssignedColor { get; set; } = string.Empty;
    public Position SpawnPoint { get; set; } = new();
    public Territory InitialTerritory { get; set; } = new();
    public int PlayerNumber { get; set; }
    public List<string> Messages { get; set; } = new();
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 位置更新结果
/// </summary>
public class PositionUpdateResult
{
    public bool Success { get; set; }
    public Position OldPosition { get; set; } = new();
    public Position NewPosition { get; set; } = new();
    public float DistanceMoved { get; set; }
    public float CurrentSpeed { get; set; }
    public bool CollisionDetected { get; set; }
    public PlayerCollisionInfo? CollisionInfo { get; set; }
    public List<string> Events { get; set; } = new();
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 画线结束结果
/// </summary>
public class DrawingEndResult
{
    public bool Success { get; set; }
    public Position EndPosition { get; set; } = new();
    public List<Position> CompletedTrail { get; set; } = new();
    public Territory? NewTerritory { get; set; }
    public float AreaGained { get; set; }
    public bool IsClosedLoop { get; set; }
    public List<string> Messages { get; set; } = new();
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 玩家碰撞处理结果
/// </summary>
public class PlayerCollisionHandleResult
{
    public bool Success { get; set; }
    public bool PlayerDied { get; set; }
    public Guid? KillerId { get; set; }
    public string? KillerName { get; set; }
    public List<Position> ClearedTrail { get; set; } = new();
    public string DeathReason { get; set; } = string.Empty;
    public bool ShieldBlocked { get; set; }
    public List<string> Messages { get; set; } = new();
}

/// <summary>
/// 死亡结果
/// </summary>
public class DeathResult
{
    public bool Success { get; set; }
    public string DeathReason { get; set; } = string.Empty;
    public Guid? KillerId { get; set; }
    public string? KillerName { get; set; }
    public Position DeathPosition { get; set; } = new();
    public List<Position> ClearedTrail { get; set; } = new();
    public DateTime RespawnTime { get; set; }
    public List<string> Messages { get; set; } = new();
}

/// <summary>
/// 复活结果
/// </summary>
public class RespawnResult
{
    public bool Success { get; set; }
    public Position RespawnPosition { get; set; } = new();
    public DateTime InvulnerabilityEndTime { get; set; }
    public TimeSpan InvulnerabilityDuration { get; set; } = TimeSpan.FromSeconds(5);
    public List<string> Messages { get; set; } = new();
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 领地计算结果
/// </summary>
public class TerritoryResult
{
    public bool Success { get; set; }
    public float TotalArea { get; set; }
    public List<Territory> Territories { get; set; } = new();
    public int TerritoryCount { get; set; }
    public float AreaPercentage { get; set; }
    public List<string> Messages { get; set; } = new();
}

/// <summary>
/// 道具拾取结果
/// </summary>
public class ItemPickupResult
{
    public bool Success { get; set; }
    public Guid ItemId { get; set; }
    public DrawingGameItemType ItemType { get; set; }
    public Position PickupPosition { get; set; } = new();
    public bool InventoryFull { get; set; }
    public int NewItemCount { get; set; }
    public List<string> Messages { get; set; } = new();
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 道具使用结果
/// </summary>
public class ItemUseResult
{
    public bool Success { get; set; }
    public DrawingGameItemType ItemType { get; set; }
    public ActiveEffect? AppliedEffect { get; set; }
    public List<Position>? ClearedTrails { get; set; }
    public List<Guid>? AffectedPlayers { get; set; }
    public Position? TargetPosition { get; set; }
    public List<string> Messages { get; set; } = new();
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 玩家碰撞信息
/// </summary>
public class PlayerCollisionInfo
{
    public DrawingGameCollisionType Type { get; set; }
    public Guid? OtherPlayerId { get; set; }
    public Position CollisionPoint { get; set; } = new();
    public string Description { get; set; } = string.Empty;
}

/// <summary>
/// 领地区域
/// </summary>
public class Territory
{
    public Guid Id { get; set; }
    public Guid PlayerId { get; set; }
    public List<Position> Boundary { get; set; } = new();
    public float Area { get; set; }
    public DateTime CapturedTime { get; set; }
    public string Color { get; set; } = string.Empty;
}

/// <summary>
/// 活跃道具效果
/// </summary>
public class ActiveEffect
{
    public Guid Id { get; set; }
    public DrawingGameItemType EffectType { get; set; }
    public DateTime StartTime { get; set; }
    public TimeSpan Duration { get; set; }
    public DateTime EndTime => StartTime.Add(Duration);
    public bool IsExpired => DateTime.UtcNow > EndTime;
    public Dictionary<string, object> Properties { get; set; } = new();
}

/// <summary>
/// 玩家游戏排名信息
/// </summary>
public class PlayerGameRanking
{
    public int Rank { get; set; }
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public string PlayerColor { get; set; } = string.Empty;
    public float TerritoryArea { get; set; }
    public int TerritoryCount { get; set; }
    public float AreaPercentage { get; set; }
    public PlayerDrawingState CurrentState { get; set; }
    public DateTime LastUpdate { get; set; }
}

/// <summary>
/// 玩家游戏统计信息
/// </summary>
public class PlayerGameStatistics
{
    public int Deaths { get; set; }
    public int Kills { get; set; }
    public float MaxTerritoryArea { get; set; }
    public float TotalDistanceMoved { get; set; }
    public int ItemsUsed { get; set; }
    public int ItemsPickedUp { get; set; }
    public TimeSpan TotalDrawingTime { get; set; }
    public int TerritoryCaptures { get; set; }
    public DateTime GameStartTime { get; set; }
    public DateTime LastActivity { get; set; }
}

#endregion
